//
//  SIDModule.swift
//  reactsdk
//
//  Created by Валиева Анна Евгеньевна on 01.04.2024.
//

import Foundation
import SberIdSDK
import React

@objcMembers
@objc(SIDModule)
class SIDModule: NSObject, RCTBridgeModule {

  static func moduleName() -> String! {
    return "SIDModule"
  }

  static func requiresMainQueueSetup() -> Bool {
    return true
  }

  func initialize(
    _ clientId: String,
    partnerName: String?,
    themeColorLight: String?,
    themeColorDark: String?,
    partnerProfileUrl: String?,
    isShowErrorOnMain: Bool,
    standType: String
  ) {
    let uiPreferences = SIDUIPreferences(
      appName: partnerName,
      themeColorLight: UIColor(hex: themeColorLight),
      themeColorDark: UIColor(hex: themeColorDark),
      isShowErrorOnMain: isShowErrorOnMain
    )
    DispatchQueue.main.async {
      SIDManager.initSberID(
        clientId: clientId,
        standType: SIDStandType(fromString: standType),
        profileUrl: partnerProfileUrl,
        uiPreferences: uiPreferences
      )
    }
  }

  func auth(
    _ scope: String,
    state: String,
    nonce: String,
    redirectUri: String,
    ssoBaseUrl: String?,
    codeChallenge: String?,
    codeChallengeMethod: String? = SIDAuthRequest.challengeMethod,
    loginHint: String?
  ) {
    let request = SIDAuthRequest(
      scope: scope,
      state: state,
      nonce: nonce,
      redirectUri: redirectUri,
      ssoBaseUrl: ssoBaseUrl,
      codeChallenge: codeChallenge,
      codeChallengeMethod: codeChallengeMethod,
      loginHint: loginHint
    )
    SIDManager.auth(
      withSberId: request,
      viewController: UIViewController.current ?? UIViewController()
    )
  }

  func loginWithIDWeb(
    _ scope: String,
    state: String,
    nonce: String,
    redirectUri: String,
    ssoBaseUrl: String?,
    codeChallenge: String?,
    codeChallengeMethod: String? = SIDAuthRequest.challengeMethod,
    loginHint: String?,
    svcRedirectUrlString: String,
    completion: @escaping RCTResponseSenderBlock
  ) {
    let request = SIDAuthRequest(
      scope: scope,
      state: state,
      nonce: nonce,
      redirectUri: redirectUri,
      ssoBaseUrl: ssoBaseUrl,
      codeChallenge: codeChallenge,
      codeChallengeMethod: codeChallengeMethod,
      loginHint: loginHint
    )


    DispatchQueue.main.async {
      let result = SIDManager.soleLoginWebPageAuth(
        sberIdRequest: request,
        svcRedirectUrlString: svcRedirectUrlString,
        viewController: UIViewController.current ?? UIViewController()
      )
      completion([result])
    }
  }

  func logout(){}

  func autoAuth(
    _ scope: String,
    state: String,
    nonce: String,
    redirectUri: String,
    ssoBaseUrl: String?,
    codeChallenge: String?,
    codeChallengeMethod: String? = SIDAuthRequest.challengeMethod,
    loginHint: String?,
    completion: @escaping RCTResponseSenderBlock
  ) {
    let request = SIDAuthRequest(
      scope: scope,
      state: state,
      nonce: nonce,
      redirectUri: redirectUri,
      ssoBaseUrl: ssoBaseUrl,
      codeChallenge: codeChallenge,
      codeChallengeMethod: codeChallengeMethod,
      loginHint: loginHint
    )
    SIDManager.autoAuth(request: request) { success in
      completion([success])
    }
  }

  func setClientID(_ clientId: String) {
    SIDManager.setClientID(clientId)
  }

  func sendOtherAuth(
    _ nameAuthService: String,
    isSuccess: Bool,
    isUserNew: Bool
  ) {
    SIDManager.sendOtherAuth(
      serviceName: nameAuthService,
      result: SIDResult(fromBool: isSuccess),
      userAuthorizationType: SIDUserAuthorizationType(fromBool: isUserNew)
    )
  }

  func setUserID(_ userID: String) {
    SIDManager.setUserID(userID)
  }

  func checkAppTokenForValid(_ completion: @escaping RCTResponseSenderBlock) {
    let result = SIDManager.checkAppTokenIsValid()
    switch result {
    case .success(let response):
      completion([NSNull(), response])
    case .failure(let error):
      completion([error.localizedDescription, NSNull()])
    }
  }

  func updateAppToken(
    _ scope: String,
    clientId: String,
    state: String,
    nonce: String,
    redirectUri: String,
    codeChallenge: String?,
    codeChallengeMethod: String?,
    completion: @escaping RCTResponseSenderBlock
  ) {
    let request = SIDAppTokenRequest(
      scope: scope,
      state: state,
      nonce: nonce,
      redirectUri: redirectUri,
      codeChallenge: codeChallenge,
      codeChallengeMethod: codeChallengeMethod
    )
    SIDManager.refreshAppToken(request: request) { result in
      switch result {
      case .success(let response):
        completion([NSNull(), response.toDictionary()])
      case .failure(let error):
        completion([error.localizedDescription, NSNull()])
      }
    }
  }

  func goToPartnerSSO(
    _ partnerWebLink: String,
    partnerClientId: String?,
    partnerColor: String?,
    openIn: String?,
    completion: @escaping RCTResponseSenderBlock
  ) {
    let result = SIDManager.goToPartnerSSO(
      partnerWebLink: partnerWebLink,
      partnerClientId: partnerClientId,
      partnerColor: UIColor(hex: partnerColor),
      openIn: SIDOpenInType(openIn)
    )
    completion([result?.localizedDescription ?? NSNull(), NSNull()])
  }

  func subscribeToAnalytic(completion: @escaping RCTResponseSenderBlock){}

  func setUIMode(uiModeString: String){}

  func setCustomFonts(
    mediumResID: Int?,
    semiBoldResID: Int?,
    completion: @escaping RCTResponseSenderBlock
  ){}

  func subscribeToAppTokenEvents(
    completion: @escaping RCTResponseSenderBlock
  ){}
}
